package cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.song;

import org.apache.wicket.RestartResponseException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.spring.injection.annot.SpringBean;

import cz.muni.fi.pa165.musiclibrary.api.service.ISongService;
import cz.muni.fi.pa165.musiclibrary.api.service.auth.IUser;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IAlbumDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IArtistDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.IGenreDTO;
import cz.muni.fi.pa165.musiclibrary.api.service.dto.ISongDTO;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.MusicLibrarySession;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.ConfirmationLink;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.FormSubmittedEvent;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.components.SongFormPanel;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.AbstractMusicLibraryPage;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.album.AlbumPage;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.artist.ArtistPage;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.genre.GenrePage;
import cz.muni.fi.pa165.musiclibrary.musiclibraryweb.pages.search.SearchPage;

/**
 *
 * @author Maros Kucbel
 * @date 2012-11-23T21:20:40+0100
 */
public final class SongPage extends AbstractMusicLibraryPage {

    @SpringBean
    private ISongService songService;

    public SongPage() {
        this(new PageParameters());
    }

    public SongPage(final PageParameters pageParameters) {
        super(pageParameters);
    }

    @Override
    public void renderHead(IHeaderResponse response) {
        
        response.render(CssHeaderItem.forReference(new CssResourceReference(SongPage.class, "SongPage.css")));
        super.renderHead(response);
    }

    @Override
    protected void onInitialize() {
        super.onInitialize();
        this.initComponents();
    }

    public void initComponents() {
        Integer id = this.getPageParameters().get("id").toOptionalInteger();
        if (id == null) {
            throw new RestartResponseException(SearchPage.class);
        }

        final ISongDTO song = songService.getById(new Long(id));

        if (song == null) {
            throw new RestartResponseException(SearchPage.class);
        }

        this.add(new Label(ComponentIDs.SONG_NAME, song.getTitle()));
        this.add(new Label(ComponentIDs.SONG_DESCRIPTION, song.getComment()));

        long length = song.getLength() != null ? song.getLength().getStandardSeconds() : 0;
        this.add(new Label(ComponentIDs.SONG_DURATION, String.format(" (%d:%02d)", (length % 3600) / 60, (length % 60))));

        IAlbumDTO album = song.getAlbum();
        PageParameters params = new PageParameters();
        params.add("id", album.getIdAlbum().toString());
        Link<Void> albumLink = new BookmarkablePageLink<Void>(ComponentIDs.ALBUM_LINK, AlbumPage.class, params);
        albumLink.add(new Label(ComponentIDs.ALBUM_LINK_NAME, album.getTitle()));
        this.add(albumLink);

        IGenreDTO genre = song.getGenre();
        params = new PageParameters();
        params.add("id", genre.getIdGenre().toString());
        Link<Void> genreLink = new BookmarkablePageLink<Void>(ComponentIDs.GENRE_LINK, GenrePage.class, params);
        genreLink.add(new Label(ComponentIDs.GENRE_LINK_NAME, genre.getName()));
        this.add(genreLink);
        
        IArtistDTO artist = song.getArtist();
        params = new PageParameters();
        params.add("id", artist.getIdArtist().toString());
        Link<Void> artistLink = new BookmarkablePageLink<Void>(ComponentIDs.ARITST_LINK, ArtistPage.class, params);
        artistLink.add(new Label(ComponentIDs.ARTIST_LINK_NAME, artist.getName()));
        this.add(artistLink);
        
        MusicLibrarySession session = MusicLibrarySession.get();
        final ModalWindow songWindow = new ModalWindow(ComponentIDs.EDIT_SONG_MODAL) {

            @Override
            public void show(AjaxRequestTarget target) {
                this.setContent(new SongFormPanel(this.getContentId(), song));
                super.show(target);
            }
        };
        this.add(songWindow);
        songWindow.setTitle(new StringResourceModel("SongPage.editSong.modal.title", this, null));
        songWindow.setMinimalWidth(500);
        songWindow.setMinimalHeight(550);
        songWindow.setInitialHeight(550);
        songWindow.setCssClassName(ModalWindow.CSS_CLASS_GRAY);
        AjaxLink editSong = new AjaxLink(ComponentIDs.EDIT_SONG_MODAL_LINK) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                songWindow.show(target);
            }

            @Override
            public void onEvent(IEvent<?> event) {
                if (songWindow.isShown() && event.getPayload() instanceof FormSubmittedEvent) {
                    FormSubmittedEvent submitted = (FormSubmittedEvent) event.getPayload();
                    songWindow.close(submitted.getTarget());
                    SongPage.this.setResponsePage(SongPage.class, SongPage.this.getPageParameters());
                }
            }
            
        };
        editSong.setVisible(session.isAuthorized());
        this.add(editSong);
        
        String deleteMessage = new StringResourceModel("SongPage.deleteSong.confirmation.message", this, null).getObject();
        ConfirmationLink<ISongDTO> deleteSong = new ConfirmationLink<ISongDTO>(ComponentIDs.DELETE_SONG_LINK, deleteMessage) {

            @Override
            public void onClick(AjaxRequestTarget target) {
                try {
                    IUser user = MusicLibrarySession.get().getUser();
                    String userName = user != null ? user.getUserName() : null;
                    SongPage.this.songService.delete(song, userName);
                    this.setResponsePage(SearchPage.class);
                } catch (Exception ex) {
                    String errorMessage = new StringResourceModel("database.delete.error", this, null).getObject();
                    target.appendJavaScript("alert('" + errorMessage + "');");
                }
            }
        };
        deleteSong.setVisible(session.isAuthorized());
        this.add(deleteSong);
    }

    /**
     * Identifiers of added components.
     */
    private static final class ComponentIDs {

        private static final String SONG_NAME = "songName";
        private static final String SONG_DESCRIPTION = "songDescription";
        private static final String SONG_DURATION = "duration";
        private static final String ALBUM_LINK = "albumLink";
        private static final String ALBUM_LINK_NAME = "albumLinkName";
        private static final String ARITST_LINK = "artistLink";
        private static final String ARTIST_LINK_NAME = "artistLinkName";
        private static final String GENRE_LINK = "genreLink";
        private static final String GENRE_LINK_NAME = "genreLinkName";
        
        private static final String EDIT_SONG_MODAL = "editSongModal";
        private static final String EDIT_SONG_MODAL_LINK = "editSongModalLink";
        
        private static final String DELETE_SONG_LINK = "deleteSongLink";
    }
}